package com.kun.config;

import java.util.concurrent.atomic.AtomicInteger;  

import org.apache.shiro.authc.AuthenticationInfo;  
import org.apache.shiro.authc.AuthenticationToken;  
import org.apache.shiro.authc.ExcessiveAttemptsException;  
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;  
import org.apache.shiro.cache.Cache;  
import org.apache.shiro.cache.CacheManager;  
/**
 * 自定义RetryLimitHashedCredentialsMatcher继承HashedCredentialsMatcher
 * doCredentialsMatch(AuthenticationToken token,AuthenticationInfo info)中进行身份认证的密码匹配，
 * 这里我们引入了Ehcahe用于保存用户登录次数，如果登录失败retryCount变量则会一直累加，
 * 如果登录成功，那么这个count就会从缓存中移除，从而实现了如果登录次数超出指定的值就锁定。
 * */
public class RetryLimitHashedCredentialsMatcher extends  HashedCredentialsMatcher{  
    private Cache<String, AtomicInteger> passwordRetryCache;    
        
    public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {    
        passwordRetryCache = cacheManager.getCache("passwordRetryCache");    
    }    
    
    @Override    
    public boolean doCredentialsMatch(AuthenticationToken token,    
            AuthenticationInfo info) {    
        String username = (String) token.getPrincipal();    
        // retry count + 1    
        AtomicInteger retryCount = passwordRetryCache.get(username);    
        if (retryCount == null) {    
            retryCount = new AtomicInteger(0);    
            passwordRetryCache.put(username, retryCount);    
        }    
        if (retryCount.incrementAndGet() > 5) {    
            // if retry count > 5 throw    
            throw new ExcessiveAttemptsException();    
        }    
    
        boolean matches = super.doCredentialsMatch(token, info);    
        if (matches) {    
            // clear retry count    
            passwordRetryCache.remove(username);    
        }    
        return matches;    
    }    
  
}
